package com.atguigu.gmall.index.service.impl;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.index.annotation.GmallCache;
import com.atguigu.gmall.index.feign.GmallPmsClient;
import com.atguigu.gmall.index.service.IndexService;
import com.atguigu.gmall.pms.entity.CategoryEntity;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class IndexServiceImpl implements IndexService {

    @Autowired
    private GmallPmsClient pmsClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private static final String KEY_PREFIX = "index:cates:";
    private static final String LOCK_PREFIX = "index:cates:lock:";

    @Override
    public List<CategoryEntity> queryLvl1Categories() {
        ResponseVo<List<CategoryEntity>> responseVo = pmsClient.queryCategoriesByPid(0L);
        return responseVo.getData();
    }

    @Override
    @GmallCache(prefix = KEY_PREFIX, timeout = 259200, random = 43200, lock = LOCK_PREFIX)
    public List<CategoryEntity> queryLvl2WithSubsByPid(Long pid) {
        ResponseVo<List<CategoryEntity>> responseVo = pmsClient.queryLvl2WithSubsByPid(pid);
        List<CategoryEntity> categoryEntities = responseVo.getData();
        return categoryEntities;
    }

//    @Override
//    public List<CategoryEntity> queryLvl2WithSubsByPid(Long pid) {
//        // 1.先查缓存，如果命中，直接返回
//        String json = redisTemplate.opsForValue().get(KEY_PREFIX + pid);
//        if (StringUtils.isNotBlank(json)) {
//            return JSON.parseArray(json,CategoryEntity.class);
//        }
//
//        // 为了防止缓存击穿，添加分布式锁
//        RLock lock = redissonClient.getLock(LOCK_PREFIX + pid);
//        lock.lock();
//
//        try {
//            // 在阻塞获取分布式锁的过程中，可能有其他请求已经放入缓存了，此时再次确认缓存中是否存在，存在直接返回
//            String json2 = redisTemplate.opsForValue().get(KEY_PREFIX + pid);
//            if (StringUtils.isNotBlank(json2)) {
//                return JSON.parseArray(json2,CategoryEntity.class);
//            }
//
//            // 2.没有命中，直接远程调用查询数据库，放入缓存
//            ResponseVo<List<CategoryEntity>> responseVo = pmsClient.queryLvl2WithSubsByPid(pid);
//            List<CategoryEntity> categoryEntities = responseVo.getData();
//            if (CollectionUtils.isEmpty(categoryEntities)) {
//                // 为了防止缓存穿透，数据即使为null也缓存，只是缓存时间较短，一般不超过5min
//                redisTemplate.opsForValue().set(KEY_PREFIX + pid, JSON.toJSONString(categoryEntities),5, TimeUnit.MINUTES);
//            }else{
//                // 为了防止缓存雪崩，给缓存时间添加随机值
//                redisTemplate.opsForValue().set(KEY_PREFIX + pid, JSON.toJSONString(categoryEntities),90 + new Random().nextInt(15),TimeUnit.DAYS);
//            }
//            return categoryEntities;
//        } finally {
//            lock.unlock();
//        }
//
////        ResponseVo<List<CategoryEntity>> responseVo = pmsClient.queryCategoriesByPid(pid);
////        List<CategoryEntity> categoryEntities = responseVo.getData();
////        if (CollectionUtils.isEmpty(categoryEntities)) {
////            // 添加缓存null
////        }else{
////            categoryEntities.forEach(categoryEntity -> {
////                ResponseVo<List<CategoryEntity>> responseVo2 = pmsClient.queryCategoriesByPid(categoryEntity.getId());
////                List<CategoryEntity> subCategories = responseVo2.getData();
////                categoryEntity.setSubs(subCategories);
////
////            });
////        }
////        return categoryEntities;
//    }

//    @Override
//    public synchronized void testLock() {
//        String number = redisTemplate.opsForValue().get("number");
//        if (StringUtils.isBlank(number)) {
//            redisTemplate.opsForValue().set("number", "1");
//        }
//        int num = Integer.parseInt(number);
//        redisTemplate.opsForValue().set("number", String.valueOf(++num));
//    }
}
